<!-- 
    不希望触发框选的子dom，添加@mousedown.stop
 -->
<template>
  <div @mousedown="handleMouseDown">
    <div
      class="absolute opacity-40 bg-blue-600 z-50"
      :id="id"
      v-show="positionList.is_show_mask"
      :style="'width:' + mask_width + 'left:' + mask_left + 'height:' + mask_height + 'top:' + mask_top"
    ></div>
    <slot></slot>
  </div>
</template>

<script lang="ts" setup>
const props = defineProps<{ itemQuery: string; handleSelect: (node: Element, index: number) => void }>()

const id = 'mask_' + generateRandomString(8)

const positionList = reactive({
  is_show_mask: false,
  box_screen_left: 0,
  box_screen_top: 0,
  start_x: 0,
  start_y: 0,
  end_x: 0,
  end_y: 0,
})
//分别计算遮罩层的位置，大小
const mask_width = computed(() => {
  return `${Math.abs(positionList.end_x - positionList.start_x)}px;`
})
const mask_height = computed(() => {
  return `${Math.abs(positionList.end_y - positionList.start_y)}px;`
})
const mask_left = computed(() => {
  return `${Math.min(positionList.start_x, positionList.end_x) - positionList.box_screen_left}px;`
})
const mask_top = computed(() => {
  return `${Math.min(positionList.start_y, positionList.end_y) - positionList.box_screen_top}px;`
})

//鼠标按下事件
const handleMouseDown = (event: MouseEvent) => {
  positionList.is_show_mask = true
  positionList.start_x = event.clientX
  positionList.start_y = event.clientY
  positionList.end_x = event.clientX
  positionList.end_y = event.clientY
  document.body.addEventListener('mousemove', handleMouseMove) //监听鼠标移动事件
  document.body.addEventListener('mouseup', handleMouseUp) //监听鼠标抬起事件
}

function handleMouseMove(event: MouseEvent) {
  positionList.end_x = event.clientX
  positionList.end_y = event.clientY
}

function handleMouseUp() {
  document.body.removeEventListener('mousemove', handleMouseMove)
  document.body.removeEventListener('mouseup', handleMouseUp)
  positionList.is_show_mask = false
  handleDomSelect()
  resSetXY()
}

function handleDomSelect() {
  const dom_mask = window.document.querySelector(`#${id}`) as HTMLElement
  const rect_select = dom_mask.getClientRects()[0]
  // const add_list: string[] = []
  // const del_list: string[] = []
  document.querySelectorAll(props.itemQuery).forEach((node, index) => {
    const rects = node.getClientRects()[0]
    if (collide(rects, rect_select) === true) {
      props.handleSelect(node, index)
    }
  })
}
//比较checkbox盒子边界和遮罩层边界最大最小值
function collide(rect1: DOMRect, rect2: DOMRect) {
  const maxX = Math.max(rect1.x + rect1.width, rect2.x + rect2.width)
  const maxY = Math.max(rect1.y + rect1.height, rect2.y + rect2.height)
  const minX = Math.min(rect1.x, rect2.x)
  const minY = Math.min(rect1.y, rect2.y)
  return maxX - minX <= rect1.width + rect2.width && maxY - minY <= rect1.height + rect2.height
}

//清除
function resSetXY() {
  positionList.start_x = 0
  positionList.start_y = 0
  positionList.end_x = 0
  positionList.end_y = 0
}
</script>
